package org.jaruse.itext;

import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.util.StringUtils;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import org.apache.poi.ss.util.CellRangeAddress;
import org.easyexcel.ExpensesRecordExcelVo;
import org.myutil.ExcelToListReader;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import static org.easyexcel.Data2Excel.insertTotalRow;

/**
 * @ClassName Html2PDF
 * @Description
 * @Author c.w
 * @Date 2025/7/23 11:23
 * @Version 1.0.0
 */
public class Html2PDF {
	public static void main(String[] args) throws IOException, IllegalAccessException, InstantiationException, DocumentException {
		List<ExpensesRecordExcelVo> list = ExcelToListReader.readFromExcel("D:\\file\\cxtk\\加油卡\\消费记录汇总优化\\测试数据.xlsx", ExpensesRecordExcelVo.class);
		List<CellRangeAddress> mergeRangeList = new ArrayList<>();
		List<ExpensesRecordExcelVo> res = insertTotalRow(list, mergeRangeList);
		long startTime = System.currentTimeMillis();
		//html2pdf(res);
		exportPdf(res, mergeRangeList, "D:\\file\\cxtk\\加油卡\\消费记录汇总优化\\测试数据.pdf");
		long endTime = System.currentTimeMillis();
		System.out.println("exportPdf()方法耗时：" + (endTime - startTime) + "ms");
	}

	private static void html2pdf(List<ExpensesRecordExcelVo> list) throws FileNotFoundException, DocumentException {
		Document document = new Document();
		PdfWriter.getInstance(document, new FileOutputStream("C:\\Users\\15795\\Desktop\\测试数据.pdf"));

	}


	public static void exportPdf(List<ExpensesRecordExcelVo> data, List<CellRangeAddress> mergeRanges, String outputPath) {
		// 1. 初始化文档（A4 纸张，边距 36pt）
		Document document = new Document(PageSize.A4,-80,-80,10,0);
		setPageSizeHen(document);
		Map<String, List<ExpensesRecordExcelVo>> deptMap = groupRecordsByDept(data);
		try {
			// 字体设置
			BaseFont baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);

			// 创建字体对象
			Font fontTitle = new Font(baseFont, 12, Font.BOLD);//SUPPRESS
			Font fontTitle2 = new Font(baseFont, 6, Font.NORMAL);
			Font font = new Font(baseFont, 8, Font.NORMAL);//SUPPRESS
			Font font2 = new Font(baseFont, 8, Font.BOLD);//SUPPRESS

			// 2. 创建 PdfWriter
			PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(outputPath));
			document.open();
			PdfPTable table = new PdfPTable(15);
			table.setTotalWidth(new float[]{150, 50, 50, 80, 120, 80, 50, 50, 50, 100, 50, 50, 80, 80, 100});
			PdfPCell pCell = new PdfPCell(new Paragraph("加油卡消费记录明细", fontTitle));
			setAlignCenter(pCell,Element.ALIGN_CENTER,Element.ALIGN_CENTER);

			pCell.setColspan(15);
			PdfPCell pCell2 = new PdfPCell(new Paragraph("数量：L 价格：元   金额：元", fontTitle2));
			pCell2.setColspan(15);
			setAlignRight(pCell2);
			table.addCell(pCell);
			table.addCell(pCell2);

			/*Image image = Image.getInstance("D:\\file\\cxtk\\加油卡\\消费记录汇总优化\\logo.png");
			image.setAbsolutePosition(0, 400);
			document.add(image);*/

			table.addCell(getPDFCell("主卡单位", font));
			table.addCell(getPDFCell("使用部门", font));
			table.addCell(getPDFCell("副卡类型", font));
			table.addCell(getPDFCell("副卡归属", font));
			table.addCell(getPDFCell("副卡卡号", font));
			table.addCell(getPDFCell("卡片厂商", font));
			table.addCell(getPDFCell("交易类型", font));
			table.addCell(getPDFCell("金额（元）", font));
			table.addCell(getPDFCell("数量（升）", font));
			table.addCell(getPDFCell("油品", font));
			table.addCell(getPDFCell("单价（元）", font));
			table.addCell(getPDFCell("余额（元）", font));
			table.addCell(getPDFCell("业务日期", font));
			table.addCell(getPDFCell("交易时间", font));
			table.addCell(getPDFCell("交易地点", font));

			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");

			for (Map.Entry<String, List<ExpensesRecordExcelVo>> entry : deptMap.entrySet()) {
				PdfPCell cardDeptCell = getPDFCell(entry.getKey(), font);
				cardDeptCell.setRowspan(entry.getValue().size());
				table.addCell(cardDeptCell);
				List<ExpensesRecordExcelVo> list = entry.getValue();
				for (int i = 0; i < list.size(); i++) {
					ExpensesRecordExcelVo record = list.get(i);
					PdfPCell useDeptCell = getPDFCell(StrUtil.isNotBlank(record.getF_use_dept()) ? record.getF_use_dept() : "", font);
					if(record.getF_use_dept().contains("总计")){
						ExpensesRecordExcelVo recordNext = list.get(i + 1);
						if(recordNext.getF_use_dept().contains("总计")) {
							useDeptCell.setRowspan(2);
							useDeptCell.setColspan(5);
							table.addCell(useDeptCell);
						}

						table.addCell(getPDFCell(StrUtil.isNotBlank(record.getF_trading_type()) ? record.getF_trading_type() : "", font));
						table.addCell(getPDFCell(record.getF_amount() >0  ? String.format("%.2f",record.getF_amount()) : "", font));
						table.addCell(getPDFCell(record.getF_oil_quantity() > 0 ? String.format("%.2f",record.getF_oil_quantity()) : "", font));
						table.addCell(getPDFCell(StrUtil.isNotBlank(record.getF_oil_type()) ? record.getF_oil_type() : "", font));

						table.addCell(getPDFCell(record.getF_oil_price() != null  ? String.format("%.2f",record.getF_oil_price()) : "", font));
						table.addCell(getPDFCell(record.getF_balance() != null ? String.format("%.2f",record.getF_balance()) : "", font));

						if (record.getF_business_time() != null){
							table.addCell(getPDFCell(record.getF_business_time(), font));
						} else {
							table.addCell(getPDFCell("", font));
						}
						if(record.getF_trading_time() != null ){
							table.addCell(getPDFCell(sdf.format(record.getF_trading_time()), font));
						} else {
							table.addCell(getPDFCell("", font));
						}
						table.addCell(getPDFCell(StrUtil.isNotBlank(record.getF_address()) ? record.getF_address() : "", font));
						continue;
					}
					if(record.getF_use_dept().contains("小计")){
						if( i < list.size() -1 ) {
							ExpensesRecordExcelVo recordNext = list.get(i + 1);
							if(recordNext.getF_use_dept().contains("小计")){
								useDeptCell.setRowspan(2);
								useDeptCell.setColspan(5);
								table.addCell(useDeptCell);
							}

						}
						table.addCell(getPDFCell(StrUtil.isNotBlank(record.getF_trading_type()) ? record.getF_trading_type() : "", font));
						table.addCell(getPDFCell(record.getF_amount() >0  ? String.format("%.2f",record.getF_amount()) : "", font));
						table.addCell(getPDFCell(record.getF_oil_quantity() > 0 ? String.format("%.2f",record.getF_oil_quantity()) : "", font));
						table.addCell(getPDFCell(StrUtil.isNotBlank(record.getF_oil_type()) ? record.getF_oil_type() : "", font));

						table.addCell(getPDFCell(record.getF_oil_price() != null  ? String.format("%.2f",record.getF_oil_price()) : "", font));
						table.addCell(getPDFCell(record.getF_balance() != null ? String.format("%.2f",record.getF_balance()) : "", font));

						if (record.getF_business_time() != null){
							table.addCell(getPDFCell(record.getF_business_time(), font));
						} else {
							table.addCell(getPDFCell("", font));
						}
						if(record.getF_trading_time() != null ){
							table.addCell(getPDFCell(sdf.format(record.getF_trading_time()), font));
						} else {
							table.addCell(getPDFCell("", font));
						}
						table.addCell(getPDFCell(StrUtil.isNotBlank(record.getF_address()) ? record.getF_address() : "", font));
						continue;
					}

					//table.addCell(getPDFCell(StrUtil.isNotBlank(record.getF_card_dept()) ? record.getF_card_dept() : "", font));
					table.addCell(getPDFCell(StrUtil.isNotBlank(record.getF_use_dept()) ? record.getF_use_dept() : "", font));
					table.addCell(getPDFCell(StrUtil.isNotBlank(record.getF_subcard_type()) ? record.getF_subcard_type() : "", font));
					table.addCell(getPDFCell(StrUtil.isNotBlank(record.getF_car_no()) ? record.getF_car_no() : "", font));
					table.addCell(getPDFCell(StrUtil.isNotBlank(record.getF_subcard_no()) ? record.getF_subcard_no() : "", font));
					table.addCell(getPDFCell(StrUtil.isNotBlank(record.getF_subcard_company()) ? record.getF_subcard_company() : "", font));

					table.addCell(getPDFCell(StrUtil.isNotBlank(record.getF_trading_type()) ? record.getF_trading_type() : "", font));
					table.addCell(getPDFCell(record.getF_amount() >0  ? String.format("%.2f",record.getF_amount()) : "", font));
					table.addCell(getPDFCell(record.getF_oil_quantity() > 0 ? String.format("%.2f",record.getF_oil_quantity()) : "", font));
					table.addCell(getPDFCell(StrUtil.isNotBlank(record.getF_oil_type()) ? record.getF_oil_type() : "", font));

					table.addCell(getPDFCell(record.getF_oil_price() != null  ? String.format("%.2f",record.getF_oil_price()) : "", font));
					table.addCell(getPDFCell(record.getF_balance() != null ? String.format("%.2f",record.getF_balance()) : "", font));

					if (record.getF_business_time() != null){
						table.addCell(getPDFCell(record.getF_business_time(), font));
					} else {
						table.addCell(getPDFCell("", font));
					}
					if(record.getF_trading_time() != null ){
						table.addCell(getPDFCell(sdf.format(record.getF_trading_time()), font));
					} else {
						table.addCell(getPDFCell("", font));
					}
					table.addCell(getPDFCell(StrUtil.isNotBlank(record.getF_address()) ? record.getF_address() : "", font));
				}
			}

			/*for (int i = 0; i < data.size(); i++) {
				ExpensesRecordExcelVo record = data.get(i);

				table.addCell(getPDFCell(StrUtil.isNotBlank(record.getF_card_dept()) ? record.getF_card_dept() : "", font));
				table.addCell(getPDFCell(StrUtil.isNotBlank(record.getF_use_dept()) ? record.getF_use_dept() : "", font));
				table.addCell(getPDFCell(StrUtil.isNotBlank(record.getF_subcard_type()) ? record.getF_subcard_type() : "", font));
				table.addCell(getPDFCell(StrUtil.isNotBlank(record.getF_car_no()) ? record.getF_car_no() : "", font));
				table.addCell(getPDFCell(StrUtil.isNotBlank(record.getF_subcard_no()) ? record.getF_subcard_no() : "", font));
				table.addCell(getPDFCell(StrUtil.isNotBlank(record.getF_subcard_company()) ? record.getF_subcard_company() : "", font));
				table.addCell(getPDFCell(StrUtil.isNotBlank(record.getF_trading_type()) ? record.getF_trading_type() : "", font));

				table.addCell(getPDFCell(record.getF_amount() >0  ? String.format("%.2f",record.getF_amount()) : "", font));
				table.addCell(getPDFCell(record.getF_oil_quantity() > 0 ? String.format("%.2f",record.getF_oil_quantity()) : "", font));
				table.addCell(getPDFCell(StrUtil.isNotBlank(record.getF_oil_type()) ? record.getF_oil_type() : "", font));

				table.addCell(getPDFCell(record.getF_oil_price() != null  ? String.format("%.2f",record.getF_oil_price()) : "", font));
				table.addCell(getPDFCell(record.getF_balance() != null ? String.format("%.2f",record.getF_balance()) : "", font));

				if (record.getF_business_time() != null){
					table.addCell(getPDFCell(record.getF_business_time(), font));
				} else {
					table.addCell(getPDFCell("", font));
				}
				if(record.getF_trading_time() != null ){
					table.addCell(getPDFCell(sdf.format(record.getF_trading_time()), font));
				} else {
					table.addCell(getPDFCell("", font));
				}
				table.addCell(getPDFCell(StrUtil.isNotBlank(record.getF_address()) ? record.getF_address() : "", font));
			}
*/
			// 6. 将表格添加到文档
			document.add(table);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			document.close();
		}
	}

	public static PdfPCell getPDFCell(String value, Font font) {
		PdfPCell cell = new PdfPCell();
		cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setPhrase(new Phrase(value, font));
		return cell;
	}

	public static  void setPageSizeHen(Document document){
		//横向
		Rectangle pageSize = new Rectangle(PageSize.A4.getHeight(), PageSize.A4.getWidth());
		pageSize.rotate();
		document.setPageSize(pageSize);
	}
	/**
	 * @Author
	 * @Description 设置页面竖向
	 * @Date
	 * @param
	 * @return
	 **/
	public static  void setPageSizeShu(Document document){
		//竖向
		Rectangle pageSize = new Rectangle(PageSize.A4.getWidth(), PageSize.A4.getHeight());
		pageSize.rotate();
		document.setPageSize(pageSize);
	}

	public static Map<String, List<ExpensesRecordExcelVo>> groupRecordsByDept(List<ExpensesRecordExcelVo> dataList) {
		LinkedHashMap<String, List<ExpensesRecordExcelVo>> datasMap = new LinkedHashMap<>();//存放主卡单位分组后的数据
		for (int i = 0; i < dataList.size(); i++) {
			ExpensesRecordExcelVo re = dataList.get(i);
			//把键空的先用&代替
			String dtkey = (StringUtils.isEmpty(re.getF_card_dept()) ? "&" : re.getF_card_dept()) + "_";
			if (datasMap.containsKey(dtkey)) {//包含该键，更新值
				List<ExpensesRecordExcelVo> vdlist = datasMap.get(dtkey);
				vdlist.add(re);
			} else {//不包含，添加新值
				List<ExpensesRecordExcelVo> vList = new ArrayList<ExpensesRecordExcelVo>();
				vList.add(re);
				datasMap.put(dtkey, vList);
			}
		}
		return datasMap;
	}

	public static void setAlignRight(PdfPCell cell){
		cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
		cell.setVerticalAlignment(Element.ALIGN_CENTER);
	}

	public static void setAlignCenter(PdfPCell cell,int h,int v){
		cell.setHorizontalAlignment(h);
		cell.setVerticalAlignment(v);
	}
}